package com.crs.service.impl;

import com.crs.context.BaseContext;
import com.crs.dto.UserLendDTO;
import com.crs.entity.Borrow_record;
import com.crs.entity.User;
import com.crs.exception.BusinessException;
import com.crs.mapper.BorrowMapper;
import com.crs.mapper.CreditMapper;
import com.crs.mapper.ResourceMapper;
import com.crs.service.BorrowService;
import com.crs.service.CreditService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.crs.constant.EntityConstant;

import java.math.BigDecimal;
import java.time.LocalDateTime;

import static com.crs.constant.EntityConstant.ON_TIME_RETURN;
import static com.crs.constant.EntityConstant.OVERTIME_RETURN;

@Service
public class BorrowServiceImpl implements BorrowService {

    @Autowired
    private BorrowMapper borrowMapper;

    @Autowired
    private ResourceMapper resourceMapper;

    @Autowired
    private CreditService creditService;
    /**
     * 用户借用接口
     * @param userLendDTO
     */
    @Transactional
    @Override
    public void userLend(UserLendDTO userLendDTO) {
        //判断预计归还时间是否大于当前时间
        if(userLendDTO.getExpectedReturn().isBefore(LocalDateTime.now())){
            throw new BusinessException("预计归还时间必须大于当前时间");
        }

        //判断资源状态是否为1如果不为1不可借用
        if(resourceMapper.findStatus(userLendDTO.getResourceId())!=1){
            throw new BusinessException("该资源目前不可借用");
        }

        Borrow_record record = Borrow_record.builder()
                .status(1)
                .actualReturn(null)
                .adminComment(null)
                .borrowTime(null)
                .actualReturn(null)
                .penaltyAmount(null)
                .overdueDays(null)
                .adminId(null).build();
        BeanUtils.copyProperties(userLendDTO,record);
        try {
            borrowMapper.insert(record);
            resourceMapper.updateStatus(0, userLendDTO.getResourceId());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 用户归还物品
     * @param
     */
    @Transactional
    @Override
    public void userReturn(Long resourceId) {
//        首先判断用户是否有罚金，根据用户id和资源id找到对应的记录，看看有罚款
        Borrow_record borrowRecord =  borrowMapper.getBorrowRecords(resourceId, BaseContext.getCurrentId());
        if(borrowRecord == null){
            throw new BusinessException("未找到对应的借阅记录");
        }
        //不是该用户的不能归还
        if(borrowRecord.getUserId() != BaseContext.getCurrentId()){
            throw new BusinessException("不是你借用的不能归还");
        }
        if(borrowRecord.getStatus() == 3){
            throw new BusinessException("该资源已归还");
        }
        if(borrowRecord.getPenaltyAmount()!=null &&(borrowRecord.getPenaltyAmount().compareTo(new BigDecimal("0")))>0){
            //有罚金需要还清罚金
            throw new BusinessException("需要先缴纳罚金才能归还");
        }
        //更新记录表，资源状态为已归还，而且设置归还时间
        borrowMapper.userReturn(resourceId);
        //更新资源表，修改资源为可借用状态
        resourceMapper.updateStatus(1,resourceId);

        //插入引用事件表记录
        creditService.CreditEventInsert(BaseContext.getCurrentId(),ON_TIME_RETURN, borrowRecord.getId());
    }

    /**
     * 用户缴纳罚款
     * @param penaltyAmount
     * @param
     */
    @Transactional
    @Override
    public void userSubmit(BigDecimal penaltyAmount, Long RecordsId) {
        //获取用户记录
        Borrow_record borrowRecord = borrowMapper.findById(RecordsId);
        if(borrowRecord == null){
            throw new BusinessException("未找到对应的借阅记录");
        }
        if(borrowRecord.getStatus() != 4){
            throw new BusinessException("该记录不是已逾期记录");
        }
        if(borrowRecord.getPenaltyAmount()==new BigDecimal("0")||((borrowRecord.getPenaltyAmount()).compareTo(new BigDecimal("0")))==0){
            throw new BusinessException("当前没有需要缴费的金额");
        }
        if((penaltyAmount.compareTo(borrowRecord.getPenaltyAmount()))<0){
            throw new BusinessException("缴纳金额不足，还需缴纳:"+borrowRecord.getPenaltyAmount().subtract(penaltyAmount));
        }
        //首先扣除信用积分数
        creditService.CreditEventInsert(BaseContext.getCurrentId(),OVERTIME_RETURN, borrowRecord.getId());

        //TODO 修改记录的状态为已归还3

        //缴纳金额足够可以缴纳，需要清空罚款金额
        Borrow_record borrowRecord1 = Borrow_record.builder()
                .id(RecordsId)
                .build();


        //更新数据库
        borrowMapper.updatePenaltyAmount(borrowRecord1);
    }
}
